﻿using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;

namespace DVK.SP2007.UniversalClient
{
    /// <summary>
    /// Help manage metainfo element from Dvk Message.
    /// <remarks>
    /// Schemas of:
    /// http://www.riik.ee/schemas/dhl-meta-automatic
    /// http://www.riik.ee/schemas/dhl-meta-manual
    /// 
    /// Element:
    /// &lt;dhl:metainfo xmlns:mm="http://www.riik.ee/schemas/dhl-meta-manual" xmlns:ma="http://www.riik.ee/schemas/dhl-meta-automatic"&gt;
    /// </remarks>
    /// </summary>
    public class DvkMetainfoXmlPart
    {
        public const string DhlMetaAutomaticNamespace = "http://www.riik.ee/schemas/dhl-meta-automatic";
        public const string DhlMetaManualNamespace = "http://www.riik.ee/schemas/dhl-meta-manual";
        
        private XElement _metainfoElement;

        /// <summary>
        /// Gets the element.
        /// </summary>
        /// <value>The element.</value>
        public XElement Element
        {
            get
            {
                return _metainfoElement;
            }
        }

        #region ElementNames
        public static readonly XName ElementNameMetainfo = XName.Get("metainfo", DvkXml.RootNamespace);

        //Automatic
        public static readonly XName ElementNameDhlId = XName.Get("dhl_id", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlFolder = XName.Get("dhl_kaust", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlArrivalMethod = XName.Get("dhl_saabumisviis", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlArrivalDateTime = XName.Get("dhl_saabumisaeg", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlSendMethod = XName.Get("dhl_saatmisviis", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlSendDateTime = XName.Get("dhl_saatmisaeg", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlSenderOrganizationCode = XName.Get("dhl_saabumisviis", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlSenderOrganizationName = XName.Get("dhl_saatja_asutuse_nimi", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlSenderPersonCode = XName.Get("dhl_saatja_isikukood", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlRecipientOrganizationCode = XName.Get("dhl_saaja_asutuse_nr", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlRecipientOrganizationName = XName.Get("dhl_saaja_asutuse_nimi", DhlMetaAutomaticNamespace);
        public static readonly XName ElementNameDhlRecipientPersonCode = XName.Get("dhl_saaja_isikukood", DhlMetaAutomaticNamespace);

        //Manual
        //Compiler - koostaja
        public static readonly XName ElementNameCompilerOrganizationCode = XName.Get("koostaja_asutuse_nr", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerOrganizationName = XName.Get("koostaja_asutuse_nimi", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerOrganizationContact = XName.Get("koostaja_asutuse_kontakt", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerDocumentName = XName.Get("koostaja_dokumendinimi", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerDocumentType = XName.Get("koostaja_dokumendityyp", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerDocumentNr = XName.Get("koostaja_dokumendinr", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerFileName = XName.Get("koostaja_failinimi", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerFolder = XName.Get("koostaja_kataloog", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerPassword = XName.Get("koostaja_votmesona", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerSummary = XName.Get("koostaja_kokkuvote", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerDate = XName.Get("koostaja_kuupaev", DhlMetaManualNamespace);
        public static readonly XName ElementNameCompilerSituatedDocumentNr = XName.Get("seotud_dokumendinr_koostajal", DhlMetaManualNamespace);

        //Sender - saatja
        public static readonly XName ElementNameSenderDocumentNr = XName.Get("saatja_dokumendinr", DhlMetaManualNamespace);
        public static readonly XName ElementNameSenderDate = XName.Get("saatja_kuupaev", DhlMetaManualNamespace);
        public static readonly XName ElementNameSenderOrganizationContact = XName.Get("saatja_asutuse_kontakt", DhlMetaManualNamespace);
        public static readonly XName ElementNameSenderSituatedDocumentNr = XName.Get("seotud_dokumendinr_saajal", DhlMetaManualNamespace);

        //Author
        public static readonly XName ElementNameAuthorDepartment = XName.Get("autori_osakond", DhlMetaManualNamespace);
        public static readonly XName ElementNameAuthorPersonCode = XName.Get("autori_isikukood", DhlMetaManualNamespace);
        public static readonly XName ElementNameAuthorName = XName.Get("autori_nimi", DhlMetaManualNamespace);
        public static readonly XName ElementNameAuthorContact = XName.Get("autori_kontakt", DhlMetaManualNamespace);

        //Recipient - Saaja
        public static readonly XName ElementNameRecipientOrganizationCode = XName.Get("saaja_asutuse_nr", DhlMetaManualNamespace);
        public static readonly XName ElementNameRecipientPersonCode = XName.Get("saaja_isikukood", DhlMetaManualNamespace);
        public static readonly XName ElementNameRecipientPersonName = XName.Get("saaja_nimi", DhlMetaManualNamespace);
        public static readonly XName ElementNameRecipientDepartment = XName.Get("saaja_osakond", DhlMetaManualNamespace);

        //AdditionalInfo
        public static readonly XName ElementNameSituatedDvkId = XName.Get("seotud_dhl_id", DhlMetaManualNamespace);
        public static readonly XName ElementNamePrimaryFileId = XName.Get("sisu_id", DhlMetaManualNamespace);

        //  <mm:saatja_defineeritud mm:valjanimi="Mingi nimi">
        //   Mingi väärtus
        //  </mm:saatja_defineeritud>
        public static readonly XName ElementNameSenderDefinedElement = XName.Get("saatja_defineeritud", DhlMetaManualNamespace);
        public static readonly XName AttributeNameSenderDefinedFieldName = XName.Get("valjanimi", DhlMetaManualNamespace);

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="DvkMetainfoXmlPart"/> class.
        /// </summary>
        /// <param name="element">The element.</param>
        public DvkMetainfoXmlPart(XElement element)
        {
            _metainfoElement = element;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DvkMetainfoXmlPart"/> class.
        /// </summary>
        public DvkMetainfoXmlPart() : this(new XElement(ElementNameMetainfo))
        {
               
        }

        /// <summary>
        /// Adds child to the metainfo element.
        /// </summary>
        /// <param name="elementName">Name of the element.</param>
        /// <param name="elementValue">The element value.</param>
        public void AddMetainfo(XName elementName, string elementValue)
        {
            _metainfoElement.Add(new XElement(elementName, elementValue));
        }

        /// <summary>
        /// Gets the child of metainfo element.
        /// </summary>
        /// <param name="elementName">Name of the element.</param>
        /// <returns></returns>
        public XElement GetMetainfo(XName elementName)
        {
            return _metainfoElement.Element(elementName);
        }

        /// <summary>
        /// Gets custom info in metainfo element by value in attribute "valjanimi".
        /// 
        /// <remarks>
        /// Gets elements in the form of:
        /// &lt;mm:saatja_defineeritud mm:valjanimi="Mingi nimi"&gt;
        ///   Mingi väärtus
        ///&lt;/mm:saatja_defineeritud&gt;
        ///
        /// </remarks>
        /// </summary>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns></returns>
        public XElement GetCustomInfo(string fieldName)
        {
            return
                (from element in _metainfoElement.Elements(ElementNameSenderDefinedElement)
                 where element.Attribute(DvkMetainfoXmlPart.AttributeNameSenderDefinedFieldName).Value == fieldName
                 select element).Single();
        }

        /// <summary>
        /// Gets all custom info ("saatja_defineeritud") elements from metainfo element.
        /// </summary>
        /// <returns></returns>
        public List<XElement> GetAllCustomInfo()
        {
            return (from element in _metainfoElement.Elements(ElementNameSenderDefinedElement)
                    select element).ToList();


        }

        /// <summary>
        /// Adds the custom info element to metainfo.
        /// </summary>
        /// <param name="fieldName">Name of the field.</param>
        /// <param name="fieldValue">The field value.</param>
        public void AddCustomInfo(string fieldName, string fieldValue)
        {
            _metainfoElement.Add(
                        new XElement(
                            ElementNameSenderDefinedElement,
                            new XAttribute(AttributeNameSenderDefinedFieldName, fieldName),
                            fieldValue
                        )
                );
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// 
        /// Turns the metainfo XElement to XML string.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
            return _metainfoElement.ToString();
        }
    }
}